home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1998 April: Mac OS SDK / Dev.CD Apr 98 SDK1.toast / Development Kits (Disc 1) / QuickDraw 3D / Samples / SampleCode / Utility Library / Box ƒ / Box.c next >
Encoding:
C/C++ Source or Header  |  1997-08-14  |  7.8 KB  |  322 lines  |  [TEXT/CWIE]

  1. /*
  2.  * Box for the utility library
  3.  *
  4.  * This is a simplified version of the box application that is described in 
  5.  * develop issue 22.
  6.  *
  7.  * It uses the QuickDraw 3D utility library
  8.  *
  9.  * Nick Thompson, nickt@apple.com
  10.  * Send bugs to devsupport@apple.com
  11.  *
  12.  */
  13.  
  14. #include <stdlib.h>
  15.  
  16. #include "Q3UL.h"
  17.  
  18. #include "QD3D.h"
  19. #include "QD3DGeometry.h"
  20. #include "QD3DGroup.h"
  21. #include "QD3DMath.h"
  22. #include "QD3DShader.h"
  23. #include "QD3DTransform.h"
  24.  
  25.  
  26. #define        MYIDTYPE        theWindowRef
  27.  
  28. /*------------------------------------------------------------------------------
  29.  * types.
  30.  */ 
  31.  
  32. typedef struct DocumentRec {
  33.     TQ3GroupObject    fModel ;    /* some geometry to draw         */
  34.     TQ3Matrix4x4    fRotation;    /* the transform for the model  */
  35. } DocumentRec ;
  36.  
  37. void            MyInitWindowData( TQ3UL_WindowRef theWindowRef ) ;
  38. TQ3GroupObject    MyNewModel( void ) ;
  39.  
  40. void    MyCloseHandler( TQ3UL_WindowRef theWindowRef ) ;
  41. void     MyRedrawHandler( TQ3UL_WindowRef windowID, TQ3ViewObject viewRef ) ;
  42. void     MyIdleHandler( TQ3UL_WindowRef windowID ) ;
  43.  
  44. /*------------------------------------------------------------------------------
  45.  * 
  46.  */ 
  47.  
  48. int main(void) 
  49. {
  50.     if( Q3UL_Initialize() == kQ3Success )
  51.     {
  52.         /* make a new window */
  53.         TQ3UL_WindowRef         theWindowRef ;
  54.         
  55.         theWindowRef = Q3UL_NewWindow( 400, 400 ) ;
  56.         
  57.         /* initlialize the window data */
  58.         MyInitWindowData( theWindowRef ) ;
  59.         
  60.         /* call the library main event loop */
  61.         Q3UL_MainEventLoop() ;
  62.     }
  63. }
  64.  
  65. /*------------------------------------------------------------------------------
  66.  * 
  67.  */ 
  68.  
  69. void    MyInitWindowData(TQ3UL_WindowRef theWindowRef)
  70. {
  71.     DocumentRec        *myDocumentRec = (DocumentRec *)malloc(sizeof(DocumentRec)) ;
  72.     
  73.     /* the identifier is not really used in this app, in a larger app, it would probably
  74.      * be used to switch between window/document types 
  75.      */
  76.     long            myIdentifier = MYIDTYPE ;
  77.  
  78.     myDocumentRec->fModel = MyNewModel() ;                /* the main display group */
  79.     Q3Matrix4x4_SetIdentity(&myDocumentRec->fRotation);    /* set to the identity matrix */
  80.         
  81.     /* set the identifier for this app and stash the document record away */
  82.     Q3UL_SetPrivType( theWindowRef, myIdentifier ) ;
  83.     Q3UL_SetPrivData( theWindowRef, (void *)myDocumentRec ) ;    
  84.     
  85.     /* install handlers for the window */
  86.     Q3UL_RegisterRedraw( theWindowRef, MyRedrawHandler ) ;
  87.     Q3UL_RegisterIdle( theWindowRef, MyIdleHandler ) ;
  88.     Q3UL_RegisterCloseWindowHandler( theWindowRef, MyCloseHandler ) ;
  89.     
  90. }
  91.  
  92.  
  93. /*------------------------------------------------------------------------------
  94.  * 
  95.  */ 
  96.  
  97. void    MyCloseHandler(TQ3UL_WindowRef theWindowRef)
  98. {
  99.     unsigned long            thisType ;
  100.     
  101.     /*
  102.      * get the private data from the window reference
  103.      * first ensuring that the document is the right type.
  104.      */
  105.      
  106.     thisType = Q3UL_GetPrivType( theWindowRef ) ;
  107.     
  108.     if( thisType == MYIDTYPE )
  109.     {
  110.         DocumentRec        *thisDocument ;
  111.         thisDocument = (DocumentRec *)Q3UL_GetPrivData( theWindowRef ) ;    
  112.         
  113.         if( thisDocument->fModel != NULL )
  114.             Q3Object_Dispose( thisDocument->fModel ) ;
  115.         
  116.         if( thisDocument != NULL )    
  117.             free( thisDocument ) ;
  118.         
  119.         /* the user clicked in the close box,
  120.          * quit and bail 
  121.          */
  122.     }
  123.     
  124.     Q3UL_DestroyWindow( theWindowRef ) ;
  125.     Q3UL_Terminate() ;
  126. }
  127.  
  128. /*------------------------------------------------------------------------------
  129.  * .
  130.  */ 
  131.  
  132. void MyRedrawHandler( TQ3UL_WindowRef windowID, TQ3ViewObject viewRef ) 
  133. {
  134.     DocumentRec        *thisDocument ;
  135.     
  136.     thisDocument = (DocumentRec *)Q3UL_GetPrivData( windowID ) ;    
  137.     if( thisDocument != NULL )
  138.     {
  139.         Q3View_StartRendering( viewRef );
  140.         do {
  141.             Q3MatrixTransform_Submit( &thisDocument->fRotation, viewRef );
  142.             Q3DisplayGroup_Submit( thisDocument->fModel, viewRef );
  143.         } while (Q3View_EndRendering( viewRef ) == kQ3ViewStatusRetraverse );
  144.     }
  145. }
  146.  
  147. /*------------------------------------------------------------------------------
  148.  * 
  149.  */ 
  150.  
  151. void MyIdleHandler( 
  152.     TQ3UL_WindowRef     windowID )  
  153. {
  154.     TQ3Matrix4x4    tmp;
  155.     DocumentRec        *thisDocument ;
  156.     
  157.     thisDocument = (DocumentRec *)Q3UL_GetPrivData( windowID ) ;    
  158.     if( thisDocument != NULL )
  159.     {        
  160.         Q3Matrix4x4_SetRotate_XYZ(&tmp, 0.1, 0.12, 0.08);
  161.         Q3Matrix4x4_Multiply(&thisDocument->fRotation, &tmp, &thisDocument->fRotation) ;
  162.     }
  163.     Q3UL_RedrawWindow( windowID ) ;
  164.  
  165. }
  166.  
  167.  
  168. /*------------------------------------------------------------------------------
  169.  * 
  170.  */ 
  171.  
  172.  
  173. void MyColorBoxFaces( 
  174.     TQ3BoxData         *myBoxData )
  175. {
  176.     TQ3ColorRGB                faceColor ;
  177.     short                     face ;
  178.     
  179.     /* sanity check - you need to have set up 
  180.      * the face attribute set for the box data 
  181.      * before calling this.
  182.      */
  183.     
  184.     if( myBoxData->faceAttributeSet == NULL )
  185.         return ;
  186.         
  187.     /* make each face of a box a different color */
  188.     
  189.     for( face = 0; face < 6; face++) {
  190.         
  191.         myBoxData->faceAttributeSet[face] = Q3AttributeSet_New();
  192.         switch( face ) {
  193.             case 0:
  194.                 faceColor.r = 1.0;
  195.                 faceColor.g = 0.0;
  196.                 faceColor.b = 0.0;
  197.                 break;
  198.             
  199.             case 1:
  200.                 faceColor.r = 0.0;
  201.                 faceColor.g = 1.0;
  202.                 faceColor.b = 0.0;
  203.                 break;
  204.             
  205.             case 2:
  206.                 faceColor.r = 0.0;
  207.                 faceColor.g = 0.0;
  208.                 faceColor.b = 1.0;
  209.                 break;
  210.             
  211.             case 3:
  212.                 faceColor.r = 1.0;
  213.                 faceColor.g = 1.0;
  214.                 faceColor.b = 0.0;
  215.                 break;
  216.             
  217.             case 4:
  218.                 faceColor.r = 1.0;
  219.                 faceColor.g = 0.0;
  220.                 faceColor.b = 1.0;
  221.                 break;
  222.             
  223.             case 5:
  224.                 faceColor.r = 0.0;
  225.                 faceColor.g = 1.0;
  226.                 faceColor.b = 1.0;
  227.                 break;
  228.         }
  229.         Q3AttributeSet_Add(myBoxData->faceAttributeSet[face], 
  230.                     kQ3AttributeTypeDiffuseColor, &faceColor);
  231.     }
  232. }
  233.  
  234. /*------------------------------------------------------------------------------
  235.  * 
  236.  */ 
  237.  
  238. TQ3GroupPosition MyAddTransformedObjectToGroup( 
  239.     TQ3GroupObject        theGroup, 
  240.     TQ3Object            theObject, 
  241.     TQ3Vector3D            *translation )
  242. {
  243.     TQ3TransformObject    transform;
  244.  
  245.     transform = Q3TranslateTransform_New(translation);
  246.     Q3Group_AddObject(theGroup, transform);    
  247.     Q3Object_Dispose(transform);
  248.     return Q3Group_AddObject(theGroup, theObject);    
  249. }
  250.  
  251. /*------------------------------------------------------------------------------
  252.  * 
  253.  */ 
  254.  
  255. TQ3GroupObject MyNewModel( void )
  256. {
  257.     TQ3GroupObject            myGroup = NULL;
  258.     TQ3GeometryObject        myBox;
  259.     TQ3BoxData                myBoxData;
  260.     TQ3ShaderObject            myIlluminationShader ;
  261.     TQ3Vector3D                translation;
  262.     
  263.     TQ3SetObject                faces[6] ;
  264.     short                    face ;
  265.             
  266.     /* Create a group for the complete model.
  267.      * do not use Q3OrderedDisplayGroup_New since in this
  268.      * type of group all of the translations are applied before
  269.      * the objects in the group are drawn, in this instance we 
  270.      * dont want this.
  271.      */
  272.     if ((myGroup = Q3DisplayGroup_New()) != NULL ) {
  273.             
  274.         /* Define a shading type for the group
  275.          * and add the shader to the group
  276.          */
  277.         myIlluminationShader = Q3PhongIllumination_New();
  278.         Q3Group_AddObject(myGroup, myIlluminationShader);
  279.  
  280.         /* set up the colored faces for the box data */
  281.         myBoxData.faceAttributeSet = faces;
  282.         myBoxData.boxAttributeSet = nil;
  283.         MyColorBoxFaces( &myBoxData ) ;
  284.         
  285.         /* create the box itself */
  286.         Q3Point3D_Set(&myBoxData.origin, 0, 0, 0);
  287.         Q3Vector3D_Set(&myBoxData.orientation, 0, 1, 0);
  288.         Q3Vector3D_Set(&myBoxData.majorAxis, 0, 0, 1);    
  289.         Q3Vector3D_Set(&myBoxData.minorAxis, 1, 0, 0);    
  290.         myBox = Q3Box_New(&myBoxData);
  291.         
  292.         /* put four copies of the box into the group, each one with its own translation */
  293.         translation.x = 0;translation.y = 0;translation.z = 0;
  294.         MyAddTransformedObjectToGroup( myGroup, myBox, &translation ) ;
  295.         
  296.         translation.x = 2;translation.y = 0;translation.z = 0;
  297.         MyAddTransformedObjectToGroup( myGroup, myBox, &translation ) ;
  298.         
  299.         translation.x = 0;translation.y = 0;translation.z = -2;
  300.         MyAddTransformedObjectToGroup( myGroup, myBox, &translation ) ;
  301.         
  302.         translation.x = -2;translation.y = 0;translation.z = 0;
  303.         MyAddTransformedObjectToGroup( myGroup, myBox, &translation ) ;
  304.     }
  305.     
  306.     /* dispose of the objects we created here */
  307.     if( myIlluminationShader ) 
  308.         Q3Object_Dispose(myIlluminationShader);    
  309.             
  310.     for( face = 0; face < 6; face++) {
  311.         if( myBoxData.faceAttributeSet[face] != NULL )
  312.             Q3Object_Dispose(myBoxData.faceAttributeSet[face]);
  313.     }
  314.     
  315.     if( myBox ) 
  316.         Q3Object_Dispose( myBox );
  317.     
  318.     return ( myGroup );
  319. }
  320.  
  321.  
  322.